package com.cst.security.authentication.accessDecisionManager;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.MessageSource;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.security.access.AccessDecisionManager;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.authentication.InsufficientAuthenticationException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.SpringSecurityMessageSource;
import org.springframework.stereotype.Service;

import java.util.Collection;

@Service
public class AccessDecisionManagerImpl implements AccessDecisionManager {

	private final static Logger logger = LoggerFactory.getLogger(AccessDecisionManagerImpl.class);

	protected MessageSourceAccessor messages = SpringSecurityMessageSource.getAccessor();
	public void setMessageSource(MessageSource messageSource) {
		this.messages = new MessageSourceAccessor(messageSource);
	}

	@Override
	public void decide(Authentication authentication, Object o, Collection<ConfigAttribute> collection) throws AccessDeniedException, InsufficientAuthenticationException {
		Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();

		for (GrantedAuthority authority : authorities) {
			// 角色名
			String roleName = authority.getAuthority();
			logger.info("roleName:"+roleName);
			for (ConfigAttribute configAttribute : collection) {
				if (configAttribute != null && !StringUtils.isEmpty(roleName)) {
					if (configAttribute.getAttribute().equals(roleName)) {
						logger.info(" role:"+roleName+" is allowed to access ");
						return;
					}
				}
			}
		}
		logger.info("Access is denied");
		throw new AccessDeniedException(messages.getMessage(
				"AbstractAccessDecisionManager.accessDenied", "Access is denied"));
	}

	@Override
	public boolean supports(ConfigAttribute configAttribute) {
		return true;
	}

	@Override
	public boolean supports(Class<?> aClass) {
		return true;
	}
}
